home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.12 Dec 96 / Flat File Databases / Invoice Example ƒ / Functional ƒ / PartsFuncs.c < prev    next >
Encoding:
Text File  |  1996-03-02  |  10.5 KB  |  384 lines  |  [TEXT/CWIE]

  1. // READ THIS!
  2. // the code in this file is ***almost identical*** to that in CustomerFuncs.c
  3. // as such, it has not been heavily annotated.  There is a
  4. // function by function correspondence between the two files.
  5.  
  6.  
  7. //handle Part window stuff.
  8. #include "InvoiceGlobals.h"
  9. #include "BTreeDef.h"
  10. #include "BTreeProtos.h"
  11. #include "SampleHeader.h"
  12. #include "Actions.h"
  13.  
  14. //some vars local to this file
  15. static short     itemType;
  16. static Handle    item;
  17. static Rect     box;
  18. static Str255    itemString;
  19. static short    ScratchShort;
  20. static long    ScratchLong;
  21. //FindType = 1 means by num, 2 by name
  22.  
  23. Str255    PartSearchNameP;
  24. Str255    PartFoundNameP;
  25. long    PartSearchNumP;
  26. long    PartFoundNumP;
  27. FileAddr    PartCurrentAddr;
  28. short    gPartFindType = kFindByName;
  29.  
  30. #define kPopUp 6
  31. #define kPartPopUp 5
  32. #define kDoIt 1
  33.  
  34. //two utility functions; makes life much easier
  35.  
  36. void GetFromPartDialog(void);
  37. void PutToPartDialog(void);
  38.  
  39.  
  40. //the heart of the matter
  41.  
  42. short FindPartByNumber(void);
  43. short FindPartByName(void);
  44. short PartFindNextPrev(short direction);
  45. short PartInsert(void);
  46. short PartEdit(void);
  47. short PartDelete(void);
  48.  
  49.  
  50. extern void HandleErrorMsg(short theErr);
  51.  
  52.  
  53. void GetFromPartDialog(void){
  54.     //Part name id = 2
  55.     //Part num id = 3
  56.     //Part price id = 4
  57.     GetDialogItem(gPartDialog, 2, &itemType, &item, &box);
  58.     GetDialogItemText(item, itemString);
  59.     ScratchShort = (short)itemString[0];
  60.     if (ScratchShort>31)
  61.         ScratchShort = 31;
  62.     BlockMove(itemString,gPart.PartName, ScratchShort+1);
  63.     GetDialogItem(gPartDialog, 3, &itemType, &item, &box);
  64.     GetDialogItemText(item, itemString);
  65.     StringToNum(itemString,&ScratchLong);
  66.     gPart.PartNo = ScratchLong;
  67.     GetDialogItem(gPartDialog, 4, &itemType, &item, &box);
  68.     GetDialogItemText(item, itemString);
  69.     ScratchShort = (short)itemString[0];
  70.     if (ScratchShort>5)
  71.         ScratchShort = 5;
  72.     BlockMove(itemString,gPart.PartPrice, ScratchShort+1);
  73.     }
  74.  
  75. void PutToPartDialog(void){
  76.     //Part name id = 2
  77.     //Part num id = 3
  78.     //Part price id = 4
  79.     GrafPtr    oldPort;
  80.     GetPort(&oldPort);
  81.     SetPort((GrafPtr)gPartDialog);
  82.     GetDialogItem(gPartDialog, 2, &itemType, &item, &box);
  83.     ScratchShort = (short)(gPart.PartName[0]);
  84.     if (ScratchShort>31)
  85.         ScratchShort = 31;
  86.     BlockMove(gPart.PartName,itemString, ScratchShort+1);
  87.     SetDialogItemText(item, itemString);
  88.     SetDialogItem(gPartDialog, 2, itemType, item, &box);
  89.     InvalThisItemRect(gPartDialog,2);
  90.     GetDialogItem(gPartDialog, 3, &itemType, &item, &box);
  91.     ScratchLong = gPart.PartNo;
  92.     NumToString(ScratchLong,itemString);
  93.     SetDialogItemText(item, itemString);
  94.     SetDialogItem(gPartDialog, 3, itemType, item, &box);
  95.     InvalThisItemRect(gPartDialog,3);
  96.     GetDialogItem(gPartDialog, 4, &itemType, &item, &box);
  97.     ScratchShort = (short)(gPart.PartName[0]);
  98.     if (ScratchShort>5)
  99.         ScratchShort = 5;
  100.     BlockMove(gPart.PartPrice,itemString, ScratchShort+1);
  101.     SetDialogItemText(item, itemString);
  102.     SetDialogItem(gPartDialog, 4, itemType, item, &box);
  103.     InvalThisItemRect(gPartDialog,4);
  104.     BeginUpdate(gPartDialog);
  105.     DrawDialog(gPartDialog);
  106.     EndUpdate(gPartDialog);
  107.     SetPort(oldPort);
  108.     }
  109.     
  110. //these two functions could easily be made into one
  111. //do it in two for demonstrative purposes
  112. short FindPartByNumber(void){
  113.     short     FindErr= noErr;
  114.     short     StringSize;
  115.     FileAddr foundAddr;
  116.  
  117.     GetFromPartDialog();
  118.     PartSearchNumP = gPart.PartNo;
  119.     gPartFindType = kFindByNumber;
  120.     FindErr = Find_Equal(kPartNumTree,gInvoiceFCH,(Ptr)&PartSearchNumP,(Ptr)&PartFoundNumP,&foundAddr,kLongCompare);
  121.     if (FindErr != noErr) {
  122.             HandleErrorMsg(FindErr);
  123.             return FindErr;
  124.         };
  125.     FindErr = Read_Data(gInvoiceFCH, kPartSize,foundAddr,(Ptr)&gPart);
  126.     if (FindErr != noErr) {
  127.             HandleErrorMsg(FindErr);
  128.             return FindErr;
  129.         };
  130.     PutToPartDialog();
  131.     PartSearchNumP = PartFoundNumP;
  132.     PartCurrentAddr = foundAddr;
  133.     return FindErr;
  134. }
  135.  
  136. short FindPartByName(void){
  137.     short     FindErr= noErr;
  138.     short     StringSize;
  139.     FileAddr foundAddr;
  140.  
  141.     GetFromPartDialog();
  142.     StringSize = gPart.PartName[0];
  143.     if (StringSize>31)
  144.         StringSize = 31;
  145.     BlockMove((Ptr)gPart.PartName,(Ptr)PartSearchNameP,StringSize+1);
  146.     gPartFindType = kFindByName;
  147.     FindErr = Find_Equal(kPartNameTree,gInvoiceFCH,(Ptr)PartSearchNameP,(Ptr)PartFoundNameP,&foundAddr,kPStringCompare);
  148.     if (FindErr != noErr) {
  149.             HandleErrorMsg(FindErr);
  150.             return FindErr;
  151.         };
  152.     FindErr = Read_Data(gInvoiceFCH, kPartSize,foundAddr,(Ptr)&gPart);
  153.     if (FindErr != noErr) {
  154.             HandleErrorMsg(FindErr);
  155.             return FindErr;
  156.         };
  157.     PutToPartDialog();
  158.     BlockMove((Ptr)PartFoundNameP,(Ptr)PartSearchNameP, 256);
  159.     PartCurrentAddr = foundAddr;
  160.     return FindErr;
  161. }
  162.  
  163. short PartFindNextPrev(short direction){
  164.     short FindErr = noErr;
  165.     FileAddr foundAddr;
  166.     FileAddr prevAddr;
  167.     short    TreeNo;
  168.     Ptr        SearchP;
  169.     Ptr        FoundP;
  170.     CompareProcPtr Comparison;
  171.     
  172.     if (gPartFindType == kFindByNumber) {
  173.         SearchP = (Ptr)&PartSearchNumP;
  174.         FoundP    = (Ptr)&PartFoundNumP;
  175.         TreeNo = kPartNumTree;
  176.         Comparison = kLongCompare;
  177.         prevAddr = PartCurrentAddr;
  178.     }
  179.     else {
  180.         SearchP = (Ptr)PartSearchNameP;
  181.         FoundP = (Ptr)PartFoundNameP;
  182.         TreeNo = kPartNameTree;
  183.         Comparison = kPStringCompare;
  184.         prevAddr = PartCurrentAddr;
  185.     };
  186.     
  187.     if (direction == kNext) 
  188.         FindErr = Find_Next(TreeNo, gInvoiceFCH, SearchP, prevAddr, FoundP, &foundAddr, Comparison);
  189.     else
  190.         FindErr = Find_Previous(TreeNo, gInvoiceFCH, SearchP, prevAddr, FoundP, &foundAddr, Comparison);
  191.     if (FindErr != noErr) {
  192.             HandleErrorMsg(FindErr);
  193.             return FindErr;
  194.     };
  195.     FindErr = Read_Data(gInvoiceFCH, kPartSize,foundAddr,(Ptr)&gPart);
  196.     if (FindErr != noErr) {
  197.             HandleErrorMsg(FindErr);
  198.             return FindErr;
  199.         };
  200.     PutToPartDialog();
  201.     PartCurrentAddr = foundAddr;
  202.     if (gPartFindType == kFindByNumber)
  203.         PartSearchNumP = PartFoundNumP;
  204.     else
  205.         BlockMove((Ptr)PartFoundNameP,(Ptr)PartSearchNameP, 256);
  206.     return FindErr;                
  207. }
  208.  
  209. short PartInsert(void) {
  210.     short     InsertErr = noErr;
  211.     FileAddr    InsertAddr;
  212.     short    AlertReturn;
  213.     short    StringSize;    
  214.     //first,check and make sure that the proposed ID number is not in the tree
  215.     GetFromPartDialog();
  216.     PartSearchNumP = gPart.PartNo;
  217.     InsertErr = Find_Equal(kPartNumTree,gInvoiceFCH,(Ptr)&PartSearchNumP,(Ptr)&PartFoundNumP,&InsertAddr,kLongCompare);
  218.     if (PartSearchNumP == PartFoundNumP) {
  219.         AlertReturn = CautionAlert(130, NULL);
  220.         InsertErr = paramErr;
  221.         return paramErr;
  222.         };
  223.     //get file space
  224.     InsertErr = Get_Bytes(gInvoiceFCH, &InsertAddr, kPartSize);
  225.     if (InsertErr != noErr) {
  226.         HandleErrorMsg(InsertErr);
  227.         return InsertErr;
  228.         };
  229.     //write the record to file
  230.     InsertErr = Write_Data(gInvoiceFCH, kPartSize, InsertAddr, (Ptr)&gPart);
  231.     if (InsertErr != noErr) {
  232.         HandleErrorMsg(InsertErr);
  233.         return InsertErr;
  234.         };
  235.     //insert the keys
  236.     InsertErr = Insert_Key(kPartNumTree, kUniqueKeys, gInvoiceFCH,(Ptr)&PartSearchNumP, InsertAddr, kLongCompare);
  237.     if (InsertErr != noErr) {
  238.         HandleErrorMsg(InsertErr);
  239.         return InsertErr;
  240.         // if for real, should also delete the record and release file space if failed insertion
  241.         };
  242.     StringSize = gPart.PartName[0];
  243.     if (StringSize>31)
  244.         StringSize = 31;
  245.     BlockMove((Ptr)gPart.PartName,(Ptr)PartSearchNameP,StringSize+1);
  246.     InsertErr = Insert_Key(kPartNameTree, kDuplicateKeys, gInvoiceFCH,(Ptr)&PartSearchNameP, InsertAddr, kPStringCompare);
  247.     if (InsertErr != noErr) {
  248.         HandleErrorMsg(InsertErr);
  249.         return InsertErr;
  250.         // if for real, should also delete the record and release file space if failed insertion
  251.         };
  252.     PartCurrentAddr = InsertAddr;
  253.     return InsertErr;
  254. }
  255.  
  256. short PartEdit(void) {
  257.     short         EditErr = noErr;
  258.     short         AlertReturn;
  259.     FileAddr    EditAddr;
  260.     //the record in the "main buffer" should be moved to a secondary buffer
  261.     PartType    PartEdit;
  262.     
  263.     BlockMove(&gPart,&PartEdit,kPartSize);
  264.     GetFromPartDialog();
  265.     // to protect data integrity, the ID # cannot be edited
  266.     // thus, only the strings need to be compared.
  267.     // more complex approach would be needed in real app
  268.     // if strings different, insert new record, edit the key string
  269.     if (!EqualString(gPart.PartName, PartEdit.PartName, TRUE, FALSE)) {
  270.         EditAddr = PartCurrentAddr;
  271.         //overwrite the old data
  272.         EditErr = Write_Data(gInvoiceFCH, kPartSize, EditAddr, (Ptr)&gPart);
  273.         if (EditErr != noErr) {
  274.             HandleErrorMsg(EditErr);
  275.             return EditErr;
  276.             };
  277.         //Very Important. Delete the old key
  278.         EditErr = Delete_Key(kPartNameTree,kDuplicateKeys, gInvoiceFCH, (Ptr)PartEdit.PartName, &EditAddr, kPStringCompare);
  279.         if (EditErr != noErr) {
  280.             HandleErrorMsg(EditErr);
  281.             return EditErr;
  282.             };
  283.         //Insert the new Key
  284.         EditErr = Insert_Key(kPartNameTree, kDuplicateKeys, gInvoiceFCH,(Ptr)gPart.PartName, EditAddr, kPStringCompare);
  285.         if (EditErr != noErr) {
  286.             HandleErrorMsg(EditErr);
  287.             return EditErr;
  288.             };
  289.     };
  290.     PartCurrentAddr = EditAddr;
  291.     BlockMove((Ptr)gPart.PartName,(Ptr)PartSearchNameP, 256);
  292.     return EditErr;
  293. }
  294.  
  295. short PartDelete(void) {
  296.     short         DeleteErr = noErr;
  297.     short         AlertReturn;
  298.     FileAddr    DeleteAddr;
  299.     //assumes that a found, insert, edit done so there is a current record in buffer.
  300.     DeleteAddr = PartCurrentAddr;
  301.     //release keys first.  better to have orphan record than keys pointing to nowhere
  302.     DeleteErr = Delete_Key(kPartNameTree,kDuplicateKeys, gInvoiceFCH, (Ptr)gPart.PartName, &DeleteAddr, kPStringCompare);
  303.     if (DeleteErr != noErr) {
  304.         HandleErrorMsg(DeleteErr);
  305.         return DeleteErr;
  306.         };
  307.     DeleteErr = Delete_Key(kPartNumTree,kUniqueKeys, gInvoiceFCH, (Ptr)gPart.PartNo, &DeleteAddr, kLongCompare);
  308.     if (DeleteErr != noErr) {
  309.         HandleErrorMsg(DeleteErr);
  310.         return DeleteErr;
  311.         };
  312.     //release space in file
  313.     DeleteErr = Release_Bytes(gInvoiceFCH, DeleteAddr, kPartSize);
  314.     if (DeleteErr != noErr) {
  315.         HandleErrorMsg(DeleteErr);
  316.         return DeleteErr;
  317.         };
  318.     PartCurrentAddr = noAddr;
  319.     gPart.PartName[0] = 0;
  320.     gPart.PartNo = 0;
  321.     PutToPartDialog();
  322.     return DeleteErr;
  323. }
  324.  
  325. void HandlePartAction(EventRecord *theEvent, short *theItem){
  326.     short PartErr;
  327.     ControlHandle popControl;
  328.     short popValue;
  329.     switch (*theItem) {
  330.         case kPartPopUp:
  331.         popControl = GetCtlHandle(gPartDialog,kPartPopUp);
  332.         popValue = GetControlValue(popControl);
  333.         switch (popValue) {
  334.             case kFindByName:
  335.             gPartAction = kFindByName;
  336.             break;
  337.             case kFindByNumber:
  338.             gPartAction = kFindByNumber;
  339.             break;
  340.             case kNext:
  341.             gPartAction = kNext;
  342.             break;
  343.             case kPrevious:
  344.             gPartAction = kPrevious;
  345.             break;
  346.             case kInsert:
  347.             gPartAction =kInsert;
  348.             break;
  349.             case kEdit:
  350.             gPartAction = kEdit;
  351.             break;
  352.             case kDelete:
  353.             gPartAction = kDelete;
  354.             break;
  355.         };//popup value switch
  356.         break; //popup
  357.         
  358.         case kDoIt:
  359.         switch (gPartAction) {
  360.             case kFindByName:
  361.             PartErr = FindPartByName();
  362.             break;
  363.             case kFindByNumber:
  364.             PartErr = FindPartByNumber();
  365.             break;
  366.             case kNext:
  367.             PartErr = PartFindNextPrev(kNext);
  368.             break;
  369.             case kPrevious:
  370.             PartErr = PartFindNextPrev(kPrevious);
  371.             break;
  372.             case kInsert:
  373.             PartErr =PartInsert();
  374.             break;
  375.             case kEdit:
  376.             PartErr = PartEdit();
  377.             break;
  378.             case kDelete:
  379.             PartErr = PartDelete();
  380.             break;
  381.         };//gPartAction switch
  382.         break;
  383.     }//switch
  384. }//function